package com.quanyan.club.web;

import com.quanyan.api.APIResponse;
import com.quanyan.api.enums.ApiResponseEnum;
import com.quanyan.club.entity.db.TbClubOfflineMemberAccount;
import com.quanyan.club.entity.vo.req.ReqClubFinanceReport;
import com.quanyan.club.entity.vo.req.ReqClubMemberAccountStreamPage;
import com.quanyan.club.entity.vo.req.ReqClubMemberOfflineFundUpdate;
import com.quanyan.club.entity.vo.req.ReqClubMemberRecharge;
import com.quanyan.club.entity.vo.resp.*;
import com.quanyan.club.service.ClubFinanceMgmService;
import com.quanyan.club.service.ClubMemberService;
import com.quanyan.club.service.ClubWidthdrawService;
import com.quanyan.common.Plugin.PageObj;
import com.quanyan.common.utils.BeanCopierUtils;
import com.quanyan.common.utils.DateUtils;
import com.quanyan.common.utils.StringUtil;
import org.apache.commons.collections.MapUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;
import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;

/**
 * Created by zhuo.shi on 2016/6/12.
 * 1. 俱乐部绑定的账户管理
 * 2. 俱乐部的资金管理
 * 3. 俱乐部成员的资金管理
 */
@RestController
@RequestMapping("/api/club/fmg")
public class ClubFinanceMgmController extends BaseController {

    @Autowired
    private ClubFinanceMgmService clubFinanceMgmService;
    @Autowired
    private ClubMemberService clubMemberService;
    @Autowired
    private ClubWidthdrawService clubWidthdrawService;

    /**
     * 俱乐部财务管理主页面
     */
    @RequestMapping(value = "/index/page", method = RequestMethod.POST)
    public APIResponse indexPage(@RequestBody Map<String, String> map){
        String appVersion = map.get("ver");
        return APIResponse.returnSuccess(clubFinanceMgmService.clubFmgIndexPage(Integer.valueOf(map.get("clubId")), appVersion));
    }

    /**
     * 返回俱乐部年度财务总计
     */
    @RequestMapping("/year/finance/report")
    public APIResponse<RespClubFinanceYearReport> generateClubYearFinanceReport(@RequestBody ReqClubFinanceReport reqFinanceReport){
        Integer clubId = reqFinanceReport.getClubId();
        Date year = null;
        try {
            year = new SimpleDateFormat("yyyy").parse(reqFinanceReport.getYear());
        } catch (ParseException e) {
            return APIResponse.returnFail(reqFinanceReport.getYear() + " 年份格式错误");
        }
        if (clubId == null || year == null){
            return APIResponse.returnFail(ApiResponseEnum.PARAMETER_CANT_BE_EMPTY);
        }
        RespClubFinanceYearReport report = new RespClubFinanceYearReport();
        BigDecimal yearOnlineFund = clubFinanceMgmService.getClubOnlineFund(clubId, year, DateUtils.addMonth(year, 12));
        BigDecimal yearOfflineFund = clubFinanceMgmService.getClubOfflineFund(clubId, year, DateUtils.addMonth(year, 12));
        report.setYearOnlineFund(yearOnlineFund);
        report.setYearOfflineFund(yearOfflineFund);
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM");
        Map<String, BigDecimal> monthsFund = new TreeMap<>();
        Date month = year;
        for (int i = 1; i <= 12; i++){
            Date nextMonth = DateUtils.addMonth(month, 1);
            if (month.after(new Date())){
                continue;
            }
            BigDecimal monthOnlineFund = clubFinanceMgmService.getClubOnlineFund(clubId, month, nextMonth);
            BigDecimal monthOfflineFund = clubFinanceMgmService.getClubOfflineFund(clubId, month, nextMonth);
            monthsFund.put(sdf.format(month), monthOfflineFund.add(monthOnlineFund));
            month = DateUtils.addMonth(month, 1);
        }
        report.setMonthFunds(monthsFund);
        return APIResponse.returnSuccess(report);
    }

    /**
     * 返回俱乐部月度财务报表
     */
    @RequestMapping("/month/finance/report")
    public APIResponse<RespClubFinanceMonthReport> generateClubMonthFinanceReport(@RequestBody ReqClubFinanceReport reqFinanceReport,
                                                                                  HttpServletRequest request){
        Date month = null;
        try {
            month = new SimpleDateFormat("yyyy-MM").parse(reqFinanceReport.getMonth());
        } catch (ParseException e) {
            return APIResponse.returnFail(reqFinanceReport.getYear() + " 月份格式错误");
        }
        int clubId = reqFinanceReport.getClubId();
        int pageNo = reqFinanceReport.getPageNo() + 1;
        int pageSize = reqFinanceReport.getPageSize();
        RespClubFinanceMonthReport report = new RespClubFinanceMonthReport();
        report.setReportMonth(month);
        if (pageNo == 1) {  //只有显示第一页时返回 线上、线下、总金额
            BigDecimal onlineFund = clubFinanceMgmService.getClubOnlineFund(clubId, month, DateUtils.addMonth(month, 1));
            report.setOnlineFundTotal(onlineFund);
            BigDecimal offlineFund = clubFinanceMgmService.getClubOfflineFund(clubId, month, DateUtils.addMonth(month, 1));
            report.setOfflineFundTotal(offlineFund);
            report.setFundTotal(onlineFund.add(offlineFund));
        }
        Integer total = clubFinanceMgmService.countClubFinanceBillDetails(clubId, month);
        report.setFinanceBillDetails( PageObj.create(total, pageNo, pageSize, clubFinanceMgmService.getClubFinanceBillDetails(clubId, month, pageNo, pageSize)));
        return APIResponse.returnSuccess(report);
    }

    /**
     * 获取俱乐部成员账户分页列表
     */
    @RequestMapping("/member/accounts")
    public APIResponse getClubMemberAccounts(@RequestBody Map<String, String> map){
        if (map.isEmpty()){
            return APIResponse.returnFail(ApiResponseEnum.PARAMETER_CANT_BE_EMPTY);
        }
        int clubId = Integer.valueOf(map.get("clubId"));
        Integer pageNo = Integer.valueOf(map.get("pageNo")) + 1;
        Integer pageSize = Integer.valueOf(map.get("pageSize"));
        String appVersion = map.get("ver");

        Integer count = clubFinanceMgmService.countClubMemberAccounts(clubId);
        List<RespClubMemberAccount> clubMemberAccounts = clubFinanceMgmService.getClubMemberAccounts(clubId,
                pageNo, pageSize, appVersion);
        PageObj pageObj = PageObj.create(count, pageNo, pageSize, clubMemberAccounts);
        return APIResponse.returnSuccess(pageObj);
    }

    /**
     * 获取某俱乐部所有成员线上+线下资金总和
     */
    @RequestMapping("/member/totalfund")
    public APIResponse<BigDecimal> getClubMemberTotalFund(@RequestBody Map<String, String> map){
        String appVersion = map.get("ver");
        return APIResponse.returnSuccess(
                clubFinanceMgmService.getClubMemberTotalFund(
                        Integer.valueOf(map.get("clubId")), appVersion));
    }

    /**
     *  俱乐部财务管理员给
     *          俱乐部成员线下充值
     */
    @RequestMapping(value = "/memeber/offlinefund/recharge", method = RequestMethod.POST)
    public APIResponse<Boolean> clubMemberOfflineFundRecharge(@RequestBody ReqClubMemberOfflineFundUpdate reqUpdate, HttpServletRequest request){
        int adminUid = getUid(request, true);
        int clubId = reqUpdate.getClubId();
        if (!clubMemberService.isClubAdminMember(adminUid, clubId)){       //主席、财务管理员才有权限
            return APIResponse.returnFail(ApiResponseEnum.PERMISSION_DENIED);
        }
        int uid = reqUpdate.getUid();
        BigDecimal amount = reqUpdate.getAmount();
        String remark = reqUpdate.getRemark();
        return APIResponse.returnSuccess(clubFinanceMgmService.clubMemberOfflineFundRecharge(uid, clubId, amount, remark));
    }

    /**
     * 俱乐部财务管理员给
     *          俱乐部成员线下扣费
     */
    @RequestMapping(value = "/memeber/offlinefund/dedut", method = RequestMethod.POST)
    public APIResponse<Boolean> clubMemberOfflineFundDedut(@RequestBody ReqClubMemberOfflineFundUpdate reqUpdate, HttpServletRequest request){
        int adminUid = getUid(request, true);
        int clubId = reqUpdate.getClubId();
        if (!clubMemberService.isClubAdminMember(adminUid, clubId)){       //主席、财务管理员才有权限
            return APIResponse.returnFail(ApiResponseEnum.PERMISSION_DENIED);
        }
        int uid = reqUpdate.getUid();
        BigDecimal amount = reqUpdate.getAmount();
        String remark = reqUpdate.getRemark();
        TbClubOfflineMemberAccount account = clubFinanceMgmService.getClubMemberOfflineAccount(uid, clubId);
        if (account == null){
            return APIResponse.returnFail("此用户在俱乐部中没账户");
        }
        if (Math.abs(amount.floatValue()) > account.getMoneyTotal().floatValue()){
            return APIResponse.returnFail("此用户在俱乐部中账户余额不足");
        }
        return APIResponse.returnSuccess(clubFinanceMgmService.clubMemberOfflineFundDedut(uid, clubId, amount, remark));
    }

    /**
     * 获取俱乐部未结算的资金总额
     */
    @RequestMapping("/unsettlment/totalfund")
    public APIResponse getgetClubUnsettlmentActivityTotalFund(@RequestBody Map<String, String> map){
        return APIResponse.returnSuccess(clubFinanceMgmService.getClubUnsettlmentActivityTotalFund(Integer.valueOf(map.get("clubId"))));
    }

    /**
     * 获取俱乐部未结算的活动列表，（含未结算资金）
     * @return
     */
    @RequestMapping("/unsettlment/activities")
    public APIResponse getClubUnsettlmentActivityList(@RequestBody Map<String, String> map){
        if (map.isEmpty() || !map.containsKey("clubId")){
            return APIResponse.returnFail(ApiResponseEnum.PARAMETER_CANT_BE_EMPTY);
        }
        Integer clubId = Integer.valueOf(map.get("clubId"));
        Integer pageNo = Integer.valueOf(map.get("pageNo")) + 1;
        Integer pageSize = Integer.valueOf(map.get("pageSize"));
        int total = clubFinanceMgmService.countClubUnsettlementActivities(clubId);
        List<RespClubUnsettlementActivity> activities =  clubFinanceMgmService.getClubUnsettlementActivities(clubId, pageNo, pageSize);
        return APIResponse.returnSuccess(PageObj.create(total, pageNo, pageSize, activities));
    }

    @RequestMapping("/index/general")
    public APIResponse indexGeneral(@RequestBody Map<String, String> map){
        String appVersion = map.get("ver");
        if (map.isEmpty() || !map.containsKey("clubId")){
            return APIResponse.returnFail(ApiResponseEnum.PARAMETER_CANT_BE_EMPTY);
        }
        RespClubFmgIndexPage respClubFmgIndexPage = clubFinanceMgmService.clubFmgIndexPage(Integer.valueOf(map.get("clubId")), appVersion);
        Integer clubId = Integer.valueOf(map.get("clubId"));
        Integer pageNo = Integer.valueOf(map.get("pageNo")) + 1;
        Integer pageSize = Integer.valueOf(map.get("pageSize"));
        int total = clubFinanceMgmService.countClubUnsettlementActivities(clubId);
        List<RespClubUnsettlementActivity> activities = clubFinanceMgmService.getClubUnsettlementActivities(clubId, pageNo, pageSize);
        RespClubFmgIndexGeneral respClubFmgIndexGeneral = new RespClubFmgIndexGeneral();
        BeanCopierUtils.copyProperties(respClubFmgIndexPage,respClubFmgIndexGeneral);
        respClubFmgIndexGeneral.setPageObj(PageObj.create(total, pageNo, pageSize, activities));
        //俱乐部认证状态
        RespClubBindAccount respClubBindAccount = clubWidthdrawService.getClubUnbindAccount(clubId);
        respClubFmgIndexGeneral.setIdentityStatus(respClubBindAccount.getIdentityStatus());
        respClubFmgIndexGeneral.setCurTime(new Date());
        return APIResponse.returnSuccess(respClubFmgIndexGeneral);
    }

    /**
     * 俱乐部成员账户余额
     * @param map
     * @return
     */
    @RequestMapping(value = "/memberRemainder",method = RequestMethod.POST)
    public APIResponse<RespClubMemberRemainder> memberRemainder(@RequestBody Map map,HttpServletRequest request){
        if(null == map.get("clubId")){
            return APIResponse.returnFail("请传入必要参数");
        }
        int uid = (int)request.getAttribute("uid");

        int clubId = (int)map.get("clubId");
        RespClubMemberRemainder remainder = clubFinanceMgmService.memberRemainder(clubId,uid);
        if(null != remainder){
            return APIResponse.returnSuccess(remainder);
        }else{
            return APIResponse.returnFail("该成员账户不存在");
        }
    }

    /**
     * 俱乐部成员线上充值
     * @param reqClubMemberRecharge
     * @return
     */
    @RequestMapping(value = "/memberRecharge",method = RequestMethod.POST)
    public APIResponse memberRecharge(@Valid @RequestBody ReqClubMemberRecharge reqClubMemberRecharge,HttpServletRequest request ){
        int uid = (int)request.getAttribute("uid");
        String userClientIp = request.getRemoteAddr();

        return clubFinanceMgmService.memberRecharge(reqClubMemberRecharge,uid,userClientIp,request);

    }
    /**
     * 俱乐部成员账户明细
     * @param reqClubMemberAccountStreamPage
     * @return
     */
    @RequestMapping(value = "/memberStream",method = RequestMethod.POST)
    public APIResponse<PageObj<RespClubMemberAccountStream>> stream(@RequestBody ReqClubMemberAccountStreamPage reqClubMemberAccountStreamPage,HttpServletRequest request){
        int uid = (int) request.getAttribute("uid");
        PageObj<RespClubMemberAccountStream> pageObj = clubFinanceMgmService.memberStream(reqClubMemberAccountStreamPage,uid);
        return APIResponse.returnSuccess(pageObj);
    }

    /**
     * 俱乐部成员账户明细详情
     * @param map
     * @return
     */
    @RequestMapping(value = "/memberDetail",method = RequestMethod.POST)
    public APIResponse<RespClubMemberAccountDetail> detail(@RequestBody Map map,HttpServletRequest request){
        int uid = (int) request.getAttribute("uid");
        if(null == map.get("id")){
            return APIResponse.returnFail("请传入必要参数");
        }
        if(null == map.get("source")){
            return APIResponse.returnFail("请传入必要参数");
        }
        if(null == map.get("clubId")){
            return APIResponse.returnFail("请传入必要参数");
        }
        String source = (String) map.get("source");
        int id = (int) map.get("id");
        int clubId = (int) map.get("clubId");
        return this.clubFinanceMgmService.memberDetail(source,id,uid,clubId);
    }
}
